home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Util / Md-Mz / Momentum / MoCDEV.p < prev    next >
Encoding:
Text File  |  1992-06-10  |  22.6 KB  |  879 lines  |  [TEXT/MPS ]

  1. {------------------------------------------------------------------------------
  2. #
  3. #    Momentum CDEV
  4. #
  5. #    MoCDEV.p    -    Pascal Source
  6. #
  7. #    Versions:
  8. #
  9. #    Components:    MOCDEV.p
  10. #                        MoCDEV.make
  11. #                        MoCDEV.r
  12. #                        MoCDEV.rsrc
  13. #
  14. ------------------------------------------------------------------------------}
  15.  
  16.  
  17. UNIT MoCDEVUnit;
  18.  
  19. INTERFACE
  20.  
  21. USES
  22.     Traps, GestaltEqu, MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf, SANE;
  23.  
  24. CONST
  25.     kGetPtrGestaltSelector    = 'gPtr';
  26.     kGestaltCodeRsrcType    = 'gCOD';
  27.     kGestaltCodeRsrcID        = 128;
  28.  
  29.     MOSignature = 'moMO';        { init signature }
  30.     kPrefResType    = 'MOdt';
  31.     kPrefResNum    = -4040;
  32.  
  33. {    PreferenceFileName = 'Momentum Prefs';
  34.     cdevSignature = MOSignature;
  35.     PrefSignature = 'pref';    }
  36.  
  37.     kWantMoCkBox        = 1;
  38.     kOnlyFinderCkBox = 2;
  39.     kMoCreditsButton    = 3;
  40.     kMoFolkloreButton = 4;
  41.     kGravForceEText    = 5;
  42.     kGravClockEText    = 6;
  43.     kDeskFricEText        = 7;
  44.     kBounceFricEText    = 8;
  45.     kIconUserItem        = 9;
  46.     kCreditTextUserItem = 10;
  47.     kMoHelpButton        = 11;
  48.     kWantSoundCkBox = 12;
  49.  
  50.     BaseCdevResID        = -4040;
  51.  
  52.     kDefaultDeskFrictn    = 10;
  53.     kDefaultBouncFrictn    = 10;
  54.     kDefaultGravForce    = 10;
  55.     kDefaultClockSetting = 6;
  56.  
  57.     kDefaultAnimationSpeed    = 6;
  58.  
  59.     kBroughtToYouByResID = -4043;
  60.     kOfficialNicknameResID = -4044;
  61.  
  62.     kMoFolkloreDlogID    = -4045;
  63.     kMoCreditsDlogID    = -4046;
  64.     kMoHelpDlogID        = -4047;
  65.  
  66.  
  67. TYPE
  68.     TossParameters = record
  69.         DeskFrictn    : integer;
  70.         BouncFrictn    : integer; 
  71.         GravForce    : integer;
  72.         ClockDirection    : integer;
  73.         GravVector        : point;
  74.         MoIsRunning        : boolean;
  75.         OnlyInFinder        : boolean;
  76.         MakeSound        : integer;                    { if zero, don’t do sounds! }
  77.         SndResNum        : integer;
  78. { from here on down, are the INIT globals...
  79.         SndChannel        : SndChannelPtr;
  80.         TossVelocityV    : longint;
  81.         TossVelocityH    : longint;
  82.         RegionLoc            : point;
  83.         ElapsedTicks        : longint;
  84.         LongPosition        : LongPt;
  85.         NoMoveCycles    : integer;        }
  86.         end;
  87.  
  88.     TossParamPtr    = ^TossParameters;
  89.  
  90. {    Units for the param blk:
  91.         DeskFrictn  -     1-100
  92.         BouncFrictn  -     1-100
  93.         GravForce  -     0-100
  94.         GravDirectn  -     vector containing gravity direction w/out magnitude
  95.         GravVector  -     pixels/tick (point w/ hor & ver components) to sum with the current velocity.    }
  96.  
  97.  
  98.         CDEVDataRec = record
  99.                 MoInfo                : TossParameters;
  100.                 lastIconRes        : integer;
  101.                 IconFlipSpeed    : integer;
  102.                 lastDrawTick    : longint;
  103.                 XtraTextResID    : integer;
  104.                 XtraTextLeft    : integer;
  105.             end;
  106.         CDEVDataPtr = ^CDEVDataRec;
  107.         CDEVDataHdl = ^CDEVDataPtr;
  108.  
  109.     
  110.     
  111. FUNCTION CDEVENTRY (message, item, numItems, CPanelID: INTEGER;
  112.                                     VAR theEvent: EventRecord;
  113.                                     cdevStorage    : Handle;
  114.                                     CPDialog        : DialogPtr) : Handle;
  115.                                                 
  116. IMPLEMENTATION
  117.  
  118.  
  119. PROCEDURE DrawResPICT (picResNum: integer; pictop, picleft: integer);                                                FORWARD;
  120. PROCEDURE DrawFinderOnlyCheckBox (ckON: boolean);                                                                            FORWARD;
  121. PROCEDURE SetCheckBox (theDialog: DialogPtr; ItemNo: integer; Setting: boolean);                                FORWARD;
  122. FUNCTION GetCheckBox (theDialog: DialogPtr; ItemNo: integer): boolean;                                                FORWARD;
  123. PROCEDURE FlipCheckBox (theDialog: DialogPtr; chkItem: integer);                                                        FORWARD;
  124. PROCEDURE GetItemBounds (theDialog: DialogPtr; ItemNo: integer; var ItemBox: rect);                            FORWARD;
  125. PROCEDURE SetDItemText (theDialog: DialogPtr; ItemNo: integer; theText: Str255);                                FORWARD;
  126. FUNCTION GetDItemNum (theDialog: DialogPtr; ItemNo: Integer): integer;                                                FORWARD;
  127. PROCEDURE SetDItemNum (theDialog: DialogPtr; ItemNo, value: Integer);                                                FORWARD;
  128. PROCEDURE GetDItemText (theDialog: DialogPtr; ItemNo: Integer; VAR txt: str255);                                FORWARD;
  129. PROCEDURE ItemActivate (theDialog: DialogPtr; ItemNo: integer; turnON: boolean);                                FORWARD;
  130. FUNCTION ReadCDEVResource (rsrcType: resType; rsrcNum: integer; var dataHdl: univ handle): boolean;        FORWARD;
  131. FUNCTION WriteCDEVResource (rsrcType: resType; rsrcNum: integer; dataPtr: univ Ptr; dataSize: longint): boolean;    FORWARD;
  132. PROCEDURE ReadInMoPrefs (ConfigData: CDEVDataHdl);                                                                            FORWARD;
  133. PROCEDURE ValidateMoData (valiData: CDEVDataHdl);                                                                            FORWARD;
  134. PROCEDURE GetCurrentMoData (valiData: CDEVDataHdl; CPDialog: DialogPtr; numItems: integer);            FORWARD;
  135. PROCEDURE FillDlogWithMoData (valiData: CDEVDataHdl; CPDialog: DialogPtr; numItems: integer);            FORWARD;
  136.  
  137. PROCEDURE MoDialogs (dlogID: integer);                                                                                                FORWARD;
  138. PROCEDURE BounceAlongWithMO (cdevData: CDEVDataHdl; CPDialog: DialogPtr);                                    FORWARD;
  139.  
  140. FUNCTION GetGestaltPtrReference (VAR DataPtr: ptr): OSErr;                                                                FORWARD;
  141.  
  142.  
  143.  
  144. FUNCTION CDEVENTRY (message, item            : INTEGER;
  145.                                     numItems, CPanelID    : INTEGER;
  146.                                     VAR theEvent            : EventRecord;
  147.                                     cdevStorage                : Handle;
  148.                                     CPDialog                    : DialogPtr) : Handle;
  149. {    This is the main dispatcher. It must be the first code in the cdev.   
  150.     CDEVENTRY's dispatcher responds only to the following messages from the Control Panel:
  151.         macDev        - To indicate what machines it is available on.
  152.         initDev        - To set up some temporary storage and get the caret started.
  153.         hitDev, closeDev, updateDev, activDev, deActivDev        }
  154.  
  155. VAR
  156.     rtnTRUE     : boolean;
  157.     IsChecked    : boolean;
  158.     tempChar    : CHAR;
  159.     dataHdl        : CDEVDataHdl;
  160.     ourItem    : integer;
  161.     ItemBox    : rect;
  162.     dataPtr        : ptr;
  163.  
  164. BEGIN
  165.     IF (message = macDev)
  166.         THEN CDEVENTRY := Handle (1)            {we work on every machine}
  167.         ELSE IF (cdevStorage <> NIL) THEN BEGIN
  168.             TextFont (geneva);
  169.             CASE (message) OF
  170.                 initDev:                                            {initialize cdev}
  171.                     begin
  172.                         cdevStorage := NewHandle(SIZEOF(CDEVDataRec));        {create private storage}
  173.                         if (cdevStorage <> nil) then
  174.                             begin
  175.                                 dataHdl := CDEVDataHdl(cdevStorage);
  176.                                 ReadInMoPrefs (dataHdl);
  177.                             end;
  178.                         SelIText(CPDialog, numItems + kGravForceEText, 0, 255);
  179.  
  180.                         FillDlogWithMoData (dataHdl, CPDialog, numItems);
  181.                         with dataHdl^^ do
  182.                             begin
  183.                                 lastIconRes := -4043;
  184.                                 IconFlipSpeed := kDefaultAnimationSpeed;
  185.                                 lastDrawTick := 0;
  186.                                 IF (ODD(TickCount))
  187.                                 THEN 
  188.                                     begin
  189.                                         XtraTextResID := kBroughtToYouByResID;
  190.                                         XtraTextLeft := 107;
  191.                                     end
  192.                                 ELSE
  193.                                     begin
  194.                                         XtraTextResID := kOfficialNicknameResID;
  195.                                         XtraTextLeft := 105;
  196.                                     end;
  197.                             end;    { with }
  198.  
  199.                     end;
  200.                 hitDev:
  201.                     begin
  202.                         ourItem := item - numItems;
  203.                         dataHdl := CDEVDataHdl (cdevStorage);
  204.  
  205.                         case (ourItem) of
  206.                             kWantMoCkBox: 
  207.                                 begin
  208.                                     FlipCheckBox(CPDialog, item);
  209.                                     rtnTRUE := GetCheckBox (CPDialog, item);
  210.                                     IF (NOT rtnTRUE)
  211.                                         THEN
  212.                                             begin
  213.                                                 GetItemBounds (CPDialog, kOnlyFinderCkBox + numItems, ItemBox);
  214.                                                 ItemBox.bottom := ItemBox.bottom + 24;
  215.                                                 ItemBox.right := ItemBox.right + 24;
  216.                                                 EraseRect (ItemBox);
  217.                                             end;
  218.                                     ItemActivate (CPDialog, kOnlyFinderCkBox + numItems, rtnTRUE);
  219.                                     ItemActivate (CPDialog, kWantSoundCkBox + numItems, rtnTRUE);
  220.                                     DrawFinderOnlyCheckBox (rtnTRUE);
  221.                                 end;
  222.                             kOnlyFinderCkBox: 
  223.                                 FlipCheckBox(CPDialog, item);
  224.                             kWantSoundCkBox: 
  225.                                 FlipCheckBox(CPDialog, item);
  226.                             kMoCreditsButton:
  227.                                 MoDialogs (kMoCreditsDlogID);
  228.                             kMoFolkloreButton:
  229.                                 MoDialogs (kMoFolkloreDlogID);
  230.                             kMoHelpButton:
  231.                                 MoDialogs (kMoHelpDlogID);
  232.                             kIconUserItem:
  233.                                 with dataHdl^^ do
  234.                                     begin
  235.                                         IF (IconFlipSpeed = kDefaultAnimationSpeed)
  236.                                             THEN IconFlipSpeed := 0
  237.                                             ELSE IconFlipSpeed := kDefaultAnimationSpeed;
  238.  
  239. { << code to install current cdev params when icon is clicked on >> }
  240.                                         HLock (handle (dataHdl));
  241.                                         with MoInfo do begin
  242.                                             GetCurrentMoData (dataHdl, CPDialog, numItems);
  243.                                             ValidateMoData (dataHdl);
  244.                 
  245.                                             IF (GetGestaltPtrReference (DataPtr) = noErr)
  246.                                             THEN
  247.                                                 BlockMove (@DeskFrictn, DataPtr, sizeof (TossParameters));
  248.                                             end;
  249.                                         HUnlock (handle (dataHdl));
  250.                                     end;
  251.                             kCreditTextUserItem:
  252.                                 begin
  253.                                     with dataHdl^^ do
  254.                                         begin
  255.                                             IF (XtraTextResID = kBroughtToYouByResID)
  256.                                             THEN
  257.                                                 begin
  258.                                                     XtraTextResID := kOfficialNicknameResID;
  259.                                                     XtraTextLeft := 105;
  260.                                                 end
  261.                                             ELSE
  262.                                                 begin
  263.                                                     XtraTextResID := kBroughtToYouByResID;
  264.                                                     XtraTextLeft := 107;
  265.                                                 end;
  266.                                         end;
  267.                                     GetItemBounds (CPDialog, kCreditTextUserItem, ItemBox);
  268.                                     EraseRect (ItemBox);
  269.                                     DrawResPICT (dataHdl^^.XtraTextResID, 238, dataHdl^^.XtraTextLeft);
  270.                                 end;
  271.                             otherwise
  272.                                 ;
  273.                         end;    { case }
  274.                     end;
  275.  
  276.                 closeDev:
  277.                     begin
  278.                         dataHdl := CDEVDataHdl (cdevStorage);
  279.                         HLock (handle (dataHdl));
  280.                         with dataHdl^^, MoInfo do begin
  281.                             GetCurrentMoData (dataHdl, CPDialog, numItems);
  282.                             ValidateMoData (dataHdl);
  283.  
  284.                             IF (GetGestaltPtrReference (DataPtr) = noErr)
  285.                             THEN
  286.                                 BlockMove (@DeskFrictn, DataPtr, sizeof (TossParameters))
  287.                             ELSE
  288.                                 ourItem := Alert (-4041, nil);
  289.  
  290.                             rtnTRUE := WriteCDEVResource (kPrefResType, kPrefResNum, @DeskFrictn, sizeof (TossParameters));
  291.                             end;
  292.                         HUnlock (handle (dataHdl));
  293.                         DisposHandle (handle(dataHdl));
  294.                     end;    
  295.                 nulDev:
  296.                     BounceAlongWithMO (CDEVDataHdl (cdevStorage), CPDialog);
  297.                 updateDev:
  298.                     BEGIN
  299.                         dataHdl := CDEVDataHdl (cdevStorage);
  300.                         DrawResPICT (BaseCdevResID, 11, 105);
  301.                         BounceAlongWithMO (dataHdl, CPDialog);
  302.                         DrawFinderOnlyCheckBox (GetCheckBox (CPDialog, kWantMoCkBox + numItems));
  303.                         DrawResPICT (dataHdl^^.XtraTextResID, 238, dataHdl^^.XtraTextLeft);
  304.                     END;
  305.                 activDev:
  306.                     ;
  307.                 deActivDev:
  308.                     ;
  309.                 cutDev:
  310.                     DlgCut (CPDialog);
  311.                 copyDev:
  312.                     DlgCopy(CPDialog);
  313.                 pasteDev:
  314.                     DlgPaste (CPDialog);
  315.                 clearDev:
  316.                     DlgDelete (CPDialog);
  317.                 keyEvtDev:                                            { the dialog mgr responds to key downs }
  318.                     ;
  319.                     otherwise;
  320.                 END;  { CASE message }
  321.  
  322.             CDEVENTRY := cdevStorage;        { if (cdevStorage = NIL) on exit then ControlPanel will put up error }
  323.         END;  { cdevStorage <> NIL }
  324. END; { CDEVENTRY }
  325.  
  326.  
  327.  
  328. { ==========================   Support routines that don't KNOW MO   ========================== }
  329.  
  330.     PROCEDURE DrawResPICT (picResNum: integer; pictop, picleft: integer);
  331. { this proc assumes that the pict resource is a purgeable resource }
  332.         var
  333.             PicRect: rect;
  334.             PictHand: picHandle;
  335.     begin
  336.         PictHand := GetPicture(picResNum);
  337.         PicRect := PictHand^^.picFrame;
  338.         OffsetRect(PicRect, picleft - PicRect.left, pictop - PicRect.top);
  339.         DrawPicture(PictHand, PicRect);
  340.     end;
  341.  
  342.  
  343.     PROCEDURE SetCheckBox (theDialog: DialogPtr; ItemNo: integer; Setting: boolean);
  344. {    purpose:    change the settings of checkboxes}
  345.         const
  346.             Chk_On = 1;    {check on/off buttons}
  347.             Chk_Off = 0;
  348.         var
  349.             NumSet: Integer;
  350.             ItemTYPE: Integer;
  351.             ItemBox: Rect;
  352.             ItemHdl: Handle;
  353.     begin
  354.         IF (Setting) 
  355.         THEN
  356.             NumSet := Chk_On
  357.         ELSE
  358.             NumSet := Chk_Off;
  359.         GetDItem (theDialog, ItemNo, ItemTYPE, ItemHdl, ItemBox);
  360.         SetCtlValue (ControlHandle(ItemHdl), NumSet);
  361.     end;
  362.  
  363.  
  364.     FUNCTION GetCheckBox (theDialog: DialogPtr; ItemNo: integer): boolean;
  365.         var
  366.             NumSet: Integer;
  367.             ItemTYPE: Integer;
  368.             ItemBox: Rect;
  369.             ItemHdl: Handle;
  370.     begin
  371.         GetDItem (theDialog, ItemNo, ItemTYPE, ItemHdl, ItemBox);
  372.         NumSet := GetCtlValue (ControlHandle(ItemHdl));
  373.         GetCheckBox := (NumSet = 1);
  374.     end;
  375.  
  376.  
  377.     PROCEDURE FlipCheckBox (theDialog: DialogPtr; chkItem: integer);
  378.     var
  379.         newSetting    : boolean;
  380.     begin
  381.         newSetting := NOT GetCheckBox(theDialog, chkItem);
  382.         SetCheckBox(theDialog, chkItem, newSetting);
  383.     end;
  384.  
  385.  
  386.     PROCEDURE GetItemBounds (theDialog: DialogPtr; ItemNo: integer; VAR ItemBox: rect);
  387. {    purpose    set the contents of text box 'ItemNo' to 'theText'}
  388.         var
  389.             ItemTYPE: Integer;
  390.             ItemHdl: Handle;
  391.     begin
  392.         GetDItem(theDialog, ItemNo, ItemTYPE, ItemHdl, ItemBox);
  393.     end;
  394.  
  395.  
  396. PROCEDURE ItemActivate (theDialog        : DialogPtr;
  397.                                         ItemNo            : integer;
  398.                                         turnON            : boolean);
  399. {    Activate, deactivate, hilite buttons }
  400. CONST
  401.     LiveControl    = 0;              { Activate, deactivate, hilite buttons }
  402.     DeadControl    = 255;
  403. VAR
  404.     ItemType    : Integer;
  405.     ItemBox    : Rect;
  406.     ItemHdl        : Handle;
  407. BEGIN
  408.     GetDItem (theDialog, ItemNo, ItemType, ItemHdl, ItemBox);
  409.     IF (turnON)
  410.         THEN HiliteControl (ControlHandle (ItemHdl), LiveControl)
  411.         ELSE HiliteControl (ControlHandle (ItemHdl), DeadControl);
  412. END;
  413.  
  414.  
  415. PROCEDURE SetDItemText (theDialog: DialogPtr; ItemNo: integer; theText: Str255);
  416. {    purpose    set the contents of text box 'ItemNo' to 'theText'}
  417.         var
  418.             ItemTYPE: Integer;
  419.             ItemBox: Rect;
  420.             ItemHdl: Handle;
  421.     begin
  422.         GetDItem(theDialog, ItemNo, ItemTYPE, ItemHdl, ItemBox);
  423.         SetIText(ItemHdl, theText);
  424.     end;
  425.  
  426.  
  427. PROCEDURE GetDItemText (theDialog: DialogPtr; ItemNo: Integer; VAR txt: str255);
  428. {    return string from text box    }
  429. VAR
  430.     ItemType    : Integer;
  431.     ItemBox    : Rect;
  432.     ItemHdl        : Handle;
  433. BEGIN
  434.     GetDItem (theDialog, ItemNo, ItemType, ItemHdl, ItemBox);
  435.     GetIText (ItemHdl, txt);
  436. END;
  437.  
  438.  
  439. FUNCTION GetDItemNum (theDialog: DialogPtr; ItemNo: Integer): integer;
  440. VAR
  441.     rtnlong    : longint;
  442.     txt        : str255;
  443. BEGIN
  444.     GetDItemText (theDialog, ItemNo, txt);
  445.     StringToNum (txt, rtnlong);
  446.     GetDItemNum := rtnlong;
  447. END;
  448.  
  449.  
  450. PROCEDURE SetDItemNum (theDialog: DialogPtr; ItemNo, value: Integer);
  451. VAR
  452.     rtnlong    : longint;
  453.     txt        : str255;
  454. BEGIN
  455.     rtnlong := value;
  456.     NumToString (rtnlong, txt);
  457.     SetDItemText (theDialog, ItemNo, txt);
  458. END;
  459.  
  460.  
  461. {######################################################
  462.         Routines that we need to check for availability of Gestalt
  463. ######################################################}
  464.  
  465. FUNCTION NumToolboxTraps: Integer;
  466. begin
  467.     if NGetTrapAddress(_InitGraf, ToolTrap) = NGetTrapAddress($AA6E, ToolTrap) then
  468.         NumToolboxTraps := $200
  469.     else
  470.         NumToolboxTraps := $400;
  471. end;
  472.  
  473.  
  474. FUNCTION GetTrapType (theTrap: Integer): TrapType;
  475.     const
  476.         TrapMask = $0800;
  477. begin
  478.     if (BAND(theTrap, TrapMask) > 0) then
  479.         GetTrapType := ToolTrap
  480.     else
  481.         GetTrapType := OSTrap;
  482. end;
  483.  
  484.  
  485. FUNCTION TrapAvailable (theTrap: Integer): Boolean;
  486.     var
  487.         tType: TrapType;
  488. begin
  489.     tType := GetTrapType(theTrap);
  490.     if tType = ToolTrap then
  491.         begin
  492.             theTrap := BAND(theTrap, $07FF);
  493.             if (theTrap >= NumToolboxTraps) then
  494.                 theTrap := _Unimplemented;
  495.         end;
  496.     TrapAvailable := NGetTrapAddress(theTrap, tType) <> NGetTrapAddress(_Unimplemented, ToolTrap);
  497. end;
  498.  
  499.  
  500. FUNCTION GestaltAvailable: boolean;
  501. CONST
  502.     GestaltTrap    = $A1AD;
  503. BEGIN
  504.     GestaltAvailable := TrapAvailable (GestaltTrap);
  505. END;
  506.  
  507.  
  508. { =================================   'MO' routines   ================================= }
  509.  
  510.  
  511. FUNCTION GetGestaltPtrReference (VAR DataPtr: ptr): OSErr;        { return error }
  512. VAR
  513.     gestaltErr        : OSErr;
  514.     memLocation    : longint;
  515. BEGIN
  516.     DataPtr := nil;
  517.     GetGestaltPtrReference := -1;
  518.     IF (GestaltAvailable)
  519.     THEN
  520.         begin
  521.             gestaltErr := Gestalt (kGetPtrGestaltSelector, memLocation);
  522.             GetGestaltPtrReference := gestaltErr;
  523.             IF (gestaltErr = noErr)
  524.             THEN
  525.                 DataPtr := ptr (memLocation);
  526.         end;
  527. END;
  528.  
  529.  
  530. PROCEDURE MoDialogs (dlogID: integer);
  531. VAR
  532.     Item                : integer;
  533.     FolkloreDPtr    : DialogPtr;
  534. BEGIN
  535.     FolkloreDPtr := GetNewDialog (dlogID, NIL, pointer(-1));
  536.     REPEAT
  537.         ModalDialog (NIL, Item);
  538.     UNTIL (Item = 1);
  539.     DisposDialog (FolkloreDPtr);
  540. END;
  541.  
  542.  
  543. PROCEDURE BounceAlongWithMO (cdevData: CDEVDataHdl; CPDialog: DialogPtr);
  544. CONST
  545.     IconTop            = 11;
  546.     IconLeft        = 105;
  547. VAR
  548.     drawDelay : integer;
  549.     IcnHandle    : handle;
  550.     IRect        : rect;
  551.     nowTicks    : longint;
  552.     savePort    : grafPtr;
  553. BEGIN
  554.     nowTicks := TickCount;
  555.     drawDelay := cdevData^^.IconFlipSpeed;
  556.     IF (nowTicks > cdevData^^.lastDrawTick + DrawDelay)
  557.     THEN
  558.         begin
  559.             GetPort (savePort);
  560.             SetPort (grafPtr (CPDialog));
  561.             cdevData^^.lastDrawTick := nowTicks;
  562.             IF (cdevData^^.lastIconRes = -4043)
  563.                 THEN cdevData^^.lastIconRes := -4033
  564.                 ELSE cdevData^^.lastIconRes := cdevData^^.lastIconRes - 1;
  565.             IcnHandle := GetResource ('ICN#', cdevData^^.lastIconRes);
  566.             IF (IcnHandle <> nil)
  567.             THEN
  568.                 begin
  569.                     SetRect (IRect, IconLeft, IconTop, IconLeft + 32, IconTop + 32);
  570.                     PlotIcon (IRect, IcnHandle);
  571.                 end;
  572.             SetPort (savePort);
  573.         end;
  574. END;
  575.  
  576.  
  577. PROCEDURE DrawFinderOnlyCheckBox (ckON: boolean);
  578. BEGIN
  579.     if (ckON)
  580.         THEN DrawResPICT (-4042, 81, 168)
  581.         ELSE DrawResPICT (-4041, 81, 168);
  582. END;
  583.  
  584.  
  585. PROCEDURE FillDlogWithMoData (valiData: CDEVDataHdl; CPDialog: DialogPtr; numItems: integer);
  586. BEGIN                
  587.     HLock (handle (valiData));
  588.     with valiData^^, MoInfo do
  589.         begin
  590.             SetCheckBox (CPDialog, kWantMoCkBox + numItems, MoIsRunning);
  591.             SetCheckBox (CPDialog, kOnlyFinderCkBox + numItems, OnlyInFinder);
  592.             SetCheckBox (CPDialog, kWantSoundCkBox + numItems, (MakeSound <> 0));
  593.                 
  594.             SetDItemNum (CPDialog, kGravForceEText + numItems, GravForce);
  595.             SetDItemNum (CPDialog, kDeskFricEText + numItems, DeskFrictn);
  596.             SetDItemNum (CPDialog, kBounceFricEText + numItems, BouncFrictn);
  597.             SetDItemNum (CPDialog, kGravClockEText + numItems, ClockDirection);
  598.         end;
  599. END;
  600.  
  601.  
  602. PROCEDURE GetCurrentMoData (valiData: CDEVDataHdl; CPDialog: DialogPtr; numItems: integer);
  603. { 'valiData' already locked }
  604. VAR
  605.     IsChecked    : boolean;
  606. BEGIN
  607.     with valiData^^, MoInfo do begin
  608.         IsChecked := GetCheckBox (CPDialog, kWantMoCkBox + numItems);
  609.         MoIsRunning := IsChecked;
  610.         IsChecked := GetCheckBox (CPDialog, kOnlyFinderCkBox + numItems);
  611.         OnlyInFinder := IsChecked;
  612.         IsChecked := GetCheckBox (CPDialog, kWantSoundCkBox + numItems);
  613.         IF (IsChecked)
  614.             THEN MakeSound := 1
  615.             ELSE MakeSound := 0;
  616.  
  617.         GravForce := GetDItemNum (CPDialog, kGravForceEText + numItems);
  618.         DeskFrictn := GetDItemNum (CPDialog, kDeskFricEText + numItems);
  619.         BouncFrictn := GetDItemNum (CPDialog, kBounceFricEText + numItems);
  620.         ClockDirection := GetDItemNum (CPDialog, kGravClockEText + numItems);
  621.     end;
  622. END;
  623.  
  624.  
  625. PROCEDURE ValidateMoData (valiData: CDEVDataHdl);
  626. VAR
  627.     BadParameter    : boolean;
  628.     IsChecked            : boolean;
  629.     MoIndex, clock    : integer;
  630.     longNum            : longint;
  631.     hReal, vReal, g    : real;
  632.     typedText            : str255;
  633. BEGIN
  634.     HLock (handle (valiData));
  635.     with valiData^^, MoInfo do
  636.         begin
  637.             BadParameter := FALSE;
  638.             IF ((DeskFrictn < 1) OR (DeskFrictn > 100))
  639.             THEN
  640.                 begin
  641.                     BadParameter := TRUE;
  642.                     DeskFrictn := kDefaultDeskFrictn;
  643.                 end;
  644.  
  645.             IF ((BouncFrictn < 1) OR (BouncFrictn > 100))
  646.             THEN
  647.                 begin
  648.                     BadParameter := TRUE;
  649.                     BouncFrictn := kDefaultBouncFrictn;
  650.                 end;
  651.  
  652.             IF ((GravForce < 0) OR (GravForce > 100))
  653.             THEN
  654.                 begin
  655.                     BadParameter := TRUE;
  656.                     GravForce := kDefaultGravForce;
  657.                 end;
  658.  
  659.             IF ((ClockDirection < 1) OR (ClockDirection > 12))
  660.             THEN
  661.                 begin
  662.                     BadParameter := TRUE;
  663.                     ClockDirection := kDefaultClockSetting;
  664.                 end;
  665.  
  666.             IF (BadParameter) THEN
  667.                 MoIndex := Alert (BaseCdevResID, nil);
  668.  
  669.         { set 'GravVector' on the way out }
  670.             hReal := 0;
  671.             vReal := 0;
  672.             g := GravForce;
  673.             GravVector.h := 0;
  674.             GravVector.v := 0;
  675.             case ClockDirection of
  676.                 1:
  677.                     begin
  678.                         hReal := 0.5 * g;
  679.                         vReal := -0.866 * g;
  680.                     end;
  681.                 2:
  682.                     begin
  683.                         hReal := 0.866 * g;
  684.                         vReal := -0.5 * g;
  685.                     end;
  686.                 3:
  687.                     begin
  688.                         GravVector.h := GravForce;
  689.                         GravVector.v := 0;
  690.                     end;
  691.                 4:
  692.                     begin
  693.                         hReal := 0.866 * g;
  694.                         vReal := 0.5 * g;
  695.                     end;
  696.                 5:
  697.                     begin
  698.                         hReal := 0.5 * g;
  699.                         vReal := 0.866 * g;
  700.                     end;
  701.                 6:
  702.                     begin
  703.                         GravVector.h := 0;
  704.                         GravVector.v := GravForce;
  705.                     end;
  706.                 7:
  707.                     begin
  708.                         hReal := -0.5 * g;
  709.                         vReal := 0.866 * g;
  710.                     end;
  711.                 8:
  712.                     begin
  713.                         hReal := -0.866 * g;
  714.                         vReal := 0.5 * g;
  715.                     end;
  716.                 9:
  717.                     begin
  718.                         GravVector.h := -GravForce;
  719.                         GravVector.v := 0;
  720.                     end;
  721.                 10:
  722.                     begin
  723.                         hReal := -0.866 * g;
  724.                         vReal := -0.5 * g;
  725.                     end;
  726.                 11:
  727.                     begin
  728.                         hReal := -0.5 * g;
  729.                         vReal := -0.866 * g;
  730.                     end;
  731.                 12:
  732.                     begin
  733.                         GravVector.h := 0;
  734.                         GravVector.v := -GravForce;
  735.                     end;
  736.                 otherwise
  737.                     begin
  738.                         GravVector.h := 0;
  739.                         GravVector.v := GravForce;
  740.                         ClockDirection := kDefaultClockSetting;
  741.                     end;
  742.                 end;    { case }
  743.             IF ((hReal <> 0) OR (vReal <> 0))
  744.             THEN
  745.                 begin
  746.                     GravVector.h := ROUND (hReal);
  747.                     GravVector.v := ROUND (vReal);
  748.                 end;
  749.  
  750.         end;    { with }
  751.     HUnlock (handle (valiData));
  752. END;
  753.  
  754.  
  755.  
  756. {======================  P R E F   R O U T I N E S  =======================}
  757.  
  758.  
  759.     FUNCTION ReadCDEVResource (rsrcType: resType; rsrcNum: integer; var dataHdl: univ handle): boolean;
  760. {    Gets resource 'rsrcType' having ID# 'rsrcNum' from the currently open res file.    }
  761. {    In a cdev, the system opens the res fork.     FUNCTION returns TRUE if data was read, FALSE if not.    }
  762.     VAR
  763.         temphdl        : handle;
  764.     BEGIN
  765.         temphdl := Get1Resource (rsrcType, rsrcNum);
  766.         IF ((ResError = noErr) AND (temphdl <> nil))
  767.         THEN
  768.             begin
  769.                 dataHdl := temphdl;
  770.                 ReadCDEVResource := TRUE;
  771.             end
  772.         ELSE
  773.             begin
  774.                 dataHdl := nil;
  775.                 ReadCDEVResource := FALSE;
  776.             end;
  777.     END;    { ReadCDEVResource }
  778.  
  779.  
  780.  
  781.     FUNCTION WriteCDEVResource (rsrcType: resType; rsrcNum: integer; dataPtr: univ Ptr; dataSize: longint): boolean;
  782.     {    Writes resource 'rsrcType' having #'rsrcNum' to the open res fork.  }
  783.     {    In a cdev the is kept open by the system.    }
  784.     {    FUNCTION returns TRUE if data was read, FALSE if not.    }
  785.     VAR
  786.         hdlFlags    : signedByte;
  787.         temphdl    : handle;
  788.  
  789.                 PROCEDURE ExitOnError (ErrNum: OSErr);
  790.                 var
  791.                     ignoreErr: OSErr;
  792.                 begin
  793.                     if (ErrNum <> noErr) then
  794.                         begin
  795.                             WriteCDEVResource := FALSE;
  796.                             Exit (WriteCDEVResource);
  797.                         end;
  798.                 end;
  799.  
  800.                 PROCEDURE WriteResHandle;
  801.                 var
  802.                     ignoreErr: OSErr;
  803.                 begin
  804.                     HLock (temphdl);
  805.                     BlockMove (dataPtr, temphdl^, dataSize);
  806.                     HUnlock (temphdl);
  807.                     AddResource (temphdl, rsrcType, rsrcNum, '');
  808.                     ExitOnError (ResError);
  809.                     WriteResource (temphdl);
  810.                     ExitOnError (ResError);
  811.                     SetResAttrs (temphdl, resPurgeable);
  812.                     WriteCDEVResource := TRUE;
  813.                 end;
  814.  
  815.     begin
  816.         temphdl := Get1Resource (rsrcType, rsrcNum);
  817.         if ((ResError = noErr) AND (temphdl <> nil))
  818.         THEN
  819.             begin
  820.                 RmveResource (temphdl);
  821.                 SetHandleSize (temphdl, dataSize);
  822.                 WriteResHandle;
  823.             end
  824.         ELSE
  825.             begin
  826.                 temphdl := Newhandle (dataSize);
  827.                 IF (temphdl <> nil)
  828.                     THEN WriteResHandle
  829.                     ELSE WriteCDEVResource := FALSE;
  830.             end;
  831.     end;    { WriteCDEVResource }
  832.  
  833.  
  834.  
  835.     PROCEDURE ReadInMoPrefs (ConfigData: CDEVDataHdl);
  836.     VAR
  837.         PrefDataOnDisk    : boolean;
  838.         index                : integer;
  839.         resSize                : longint;
  840.         gravH, gravV    : integer;
  841.         DataLocation        : ptr;
  842.         SrcLocation        : ptr;
  843.         resData            : handle;
  844.     BEGIN
  845.         HLock (handle (ConfigData));
  846.         with ConfigData^^, MoInfo do begin
  847.             PrefDataOnDisk := FALSE;
  848.             DataLocation := @DeskFrictn;
  849.             PrefDataOnDisk := ReadCDEVResource (kPrefResType, kPrefResNum, resData);
  850.             IF (PrefDataOnDisk)
  851.             THEN
  852.                 begin
  853.                     HLock (handle (resData));
  854.                     SrcLocation := resData^;
  855.                     resSize := GethandleSize (resData);
  856.                     IF (resSize > sizeof (TossParameters))
  857.                         THEN resSize := sizeof (TossParameters);
  858.                     BlockMove (SrcLocation, DataLocation, resSize);
  859.                     HUnlock (handle (resData));
  860.                 end
  861.             ELSE
  862.                 begin
  863.                     { init all }
  864.                     DeskFrictn := kDefaultDeskFrictn;
  865.                     BouncFrictn := kDefaultBouncFrictn;
  866.                     GravForce := kDefaultGravForce;
  867.                     ClockDirection := kDefaultClockSetting;
  868.                     MoIsRunning := TRUE;
  869.                     OnlyInFinder := FALSE;
  870.                     MakeSound := 1;                    { if zero, don’t do sounds! }
  871.                     SndResNum := -32512;
  872.                 end;
  873.             end;
  874.         HUnlock (handle (ConfigData));
  875.     END;
  876.  
  877.  
  878. END.  { MoCDEVUnit }
  879.